package com.springboot.rigger.common.config;

import java.io.File;
import java.io.FileInputStream;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Utils {
	private static final char[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e',
			'f' };

	// 带秘钥加密
	public static String md5(String text, String salt) {
		return (text != null && salt != null) ? md5(text + salt) : md5(text);
	}

	// 根据传入的密钥进行验证
	public static boolean verify(String text, String salt, String md5) {
		return md5(text, salt).equalsIgnoreCase(md5);
	}

	public static String md5(String input) {
	    if (input == null) {
	        return null;
		}
		try {
			// 获取MD5转换器(如果想要SHA1参数换成"SHA1")
			MessageDigest md5 = MessageDigest.getInstance("MD5");

			// 输入的字符串转换成字节数组
			byte[] inputByteArray = input.getBytes(StandardCharsets.UTF_8);

			// 使用输入的字节数组更新摘要。
			md5.update(inputByteArray);

			// 转换并返回16个元素的字节数组
			byte[] resultByteArray = md5.digest();

			// 将返回的字节数组换成16进制的字符串
			return byteArrayToHex(resultByteArray);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	/**
	 * 计算文件md5
	 */
	public static String md5(File file) {
		try (FileInputStream fis = new FileInputStream(file)) {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			byte[] buffer = new byte[8192];
			int len;
			while ((len = fis.read(buffer)) != -1) {
				md5.update(buffer, 0, len);
			}
			return byteArrayToHex(md5.digest());
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	/**
	 * 将字节数组换成成16进制的字符串
	 * 
	 * @param byteArray
	 * @return
	 */
	private static String byteArrayToHex(byte[] byteArray) {
		char charArray[] = new char[byteArray.length * 2];
		int index = 0;
		for (byte b : byteArray) {
			charArray[index++] = HEX_CHARS[(b >>> 0x4) & 0xf];
			charArray[index++] = HEX_CHARS[b & 0xf];
		}
		return new String(charArray);
	}

	/**
	 * <pre>
	 * %02x
	 * x 表示以十六进制形式输出
	 * 02 表示不足两位,，前面补0输出，如果超过两位，则以实际输出
	 * </pre>
	 * 
	 * @deprecated
	 */
	private static String byteArrayToHexOld1(byte[] byteArray) {
		StringBuilder sb = new StringBuilder();
		for (byte b : byteArray) {
			sb.append(String.format("%02x", b));
		}
		return sb.toString();
	}

	/**
	 * @deprecated
	 */
	private static String byteArrayToHexOld2(byte[] byteArray) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < byteArray.length; i++) {
			int var = byteArray[i] & 0xff;
			if (var < 16)
				sb.append("0");
			sb.append(Integer.toHexString(var));
		}
		return sb.toString();
	}
}

